import '@/utils/objects'
import { defineStore } from 'pinia'
import { message } from 'ant-design-vue'
import sysConfig from '@/config/index'
import tool from '@/utils/tool'

import { globalStore } from '@/store/global'

export const ewaytelStore = defineStore({
	id: 'ewaytel',
	state: () => ({
		telInstance: null,
		connectedstate: '0', // 连接状态 0-连接中 1-已连接 2-连接错误
		talkState: 'idle', // 通话状态 outgoing-呼出中 ringback-振铃中 incoming-呼入中 outconnected-呼出接通 inconnected-呼入接通 hangup-挂断 idle-空闲 hanguping-正在挂断
		cBSwitchType: tool.data.get('CB_SWITCH_TYPE') || '1', // 换卡方式 1-顺序换卡， 2-手动换卡
		currSIMIndex: null, // 当前sim卡
		usedSimList: [], // 可用sim卡
		talkTime: '呼出接通', // 时长记录

		// 防封卡参数
		configs: {
			communicationTypeSwitch: null,
			communicationType: null,
			maxContinuousNum: null, // 单卡连续最大拨打次数
			callInterval: null // 拨号间隔
		},

		SIMContinuousCount: 0, // 单卡连续拨打次数
		dialEndTime: '' // 挂断时间
	}),
	getters: {
		// 是否连接中
		isConnecting(state) {
			return state.connectedstate === '0'
		},
		// 是否已连接
		isConnectSuccess(state) {
			return state.connectedstate === '1'
		},
		// 是否连接错误
		isConnectFail(state) {
			return state.connectedstate === '2'
		},
		// 是否通话闲置状态
		isTalkIdle(state) {
			return state.talkState === 'idle'
		}
	},
	actions: {
		// 初始化 init
		initSocket(saveDataCallback) {
			// 回调处理
			const callback = (key, value) => {
				// if (key === 'talkState') console.log('key:', key, 'value:', value)
				if (Object.keys(this).includes(key)) this[key] = value

				// 防封卡统计
				// 自动换卡累加拨打次数，超过最大拨打次数时，自动切换下一个
				if (this.cBSwitchType === '1' && key === 'talkState') {
					if (value === 'outgoing') {
						this.SIMContinuousCount++
					} else if (value === 'hangup') {
						if (this.configs.maxContinuousNum !== null && this.SIMContinuousCount >= this.configs.maxContinuousNum) {
							this.cbSwitchNext('1')
						}
					}
				}
			}
			const fail = () => {
				const store = globalStore()
				// store.dashboardNode?.close()
				if (!store.phoneData || !store.phoneData.type) {
					store.dashboardNode?.setShowType(0)
				} else {
					this.talkState = 'idle'
					this.telInstance.actionType = 1
				}
				message.warning('拨号失败，请检查SIM卡或挂断已有通话！')
			}

			// 初始化
			if (!this.telInstance) {
				// console.log('实例化')
				this.telInstance = new Tel4GTxn(callback, fail, saveDataCallback)
			}
			return this.telInstance.Init()
		},
		// 关闭 close
		close() {
			console.log('主动关闭4g连接', this.talkState)
			// 通话过程中不关闭
			if (this.telInstance && this.isTalkIdle) {
				this.telInstance.OnClose()

				this.telInstance = null
				this.connectedstate = '0' // 连接状态 0-连接中 1-已连接 2-连接错误
				this.currSIMIndex = null // 当前sim卡
				this.usedSimList = [] // 可用sim卡
			}
		},

		// 检测是否已存在 webSocket
		ifWebSocket() {
			return this.telInstance && this.telInstance.webSocketState
		},

		// 打电话
		dial(phone) {
			this.telInstance.OnDial(phone)
		},
		// 挂断
		hangup() {
			this.telInstance.OnHangup()
		},

		// 换卡
		cbSwitchNext(type, simIndex = null) {
			this.cBSwitchType = type
			tool.data.set('CB_SWITCH_TYPE', type)
			if (type === '1') {
				if (
					!this.usedSimList.length ||
					(this.usedSimList.length === 1 && this.usedSimList[0].value === this.currSIMIndex)
				) {
					return
				}

				this.telInstance.switchCardStatus = true
				this.SIMContinuousCount = 0
				this.telInstance.OnCBSwitchNext()
			}
			if (type === '2' && typeof simIndex === 'number') {
				this.telInstance.switchCardStatus = true
				this.currSIMIndex = simIndex
				this.telInstance.OnCBSwitch(simIndex)
			}
		},

		setConfigs(key) {
			this.configs = key
		}
	}
})

// 话机类
function Tel4GTxn(callback, fail, saveDataCallback) {
	this.webSocketId = null
	this.webSocket = null
	this.deviceName = null // 设备序列号
	this.webSocketState = false // socket连接状态
	this.maxReconnectNum = 3 // 最大重连次数
	this.reconnectNum = 0 // 重连计数
	this.heartBeatTimer = null // 心跳计时引用
	this.reconnectTimer = null // 断线重连计时引用
	this.actionType = 1 // 0-拨号，1-挂断
	this.switchCardStatus = false // 切卡状态

	this.baseConfig = {
		// 基础配置
		autorecordenable: true, // 自动录音开关
		autorecordfilenametype: '0', // 录音文件类型（wav格式）
		autouploadlogenable: true, // 自动上传通话记录开关
		autouploadlogurl: sysConfig.API_URL + '/call/notify/phoneCallback', // 自动上传通话记录URL
		autouploadlogtype: '1', // 上传通话记录校验开关

		autouploadenable: true, //自动上传录音文件开关
		autouploadtype: '1', //自动上传录音文件方式（阿里云）
		autouploadurl: '', //自动上传录音文件url

		// 自动上传云服务信息
		accesskeyid: 'LTAI5tQHGxWtAbj5YQ3qwNvr',
		accesskeysecret: '5ouZa0aniOo4shr9ABSpB9Qx4Pk73w',
		bucketname: 'tianyaoqfoss',
		endpoint: 'oss-cn-beijing.aliyuncs.com',
		txcospath: 'callPhone' // 存储目录
	}

	this.callback = callback
	this.fail = fail
	this.saveDataCallback = saveDataCallback

	this.initTimer = null
	this.otherCallStatus = false // 其他账号是否正在拨号 true-是 false-否

	// 计时
	this.startTime = null
	this.timingTimer = null
	this.updateTimer = () => {
		const diff = new Date().getTime() - this.startTime // 计算时间
		const hours = Math.floor(diff / 3600000)
		const minutes = Math.floor((diff % 3600000) / 60000)
		const seconds = Math.floor((diff % 60000) / 1000)

		const times = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds
			.toString()
			.padStart(2, '0')}`
		this.callback && this.callback('talkTime', times)
		// console.log('-------通话时长：', times)
	}
}

// 初始化链接
Tel4GTxn.prototype.Init = function () {
	return new Promise((resolve, reject) => {
		clearTimeout(this.initTimer)
		this.initTimer = setTimeout(() => {
			clearTimeout(this.initTimer)

			const ewaytel = ewaytelStore()

			// 期间也没有异常关闭
			if (this.webSocket && this.webSocket.readyState === 1) {
				console.log('线路复用链接话机', this.webSocket)
				this.OnOpenDevice()
				resolve()
				return
			} else {
				// 兼容异常断连
				this.clearHeartBeatTimer()
			}

			console.log('webSocket init')
			this.webSocket = new WebSocket('ws://127.0.0.1:8555/api')
			this.webSocket.nativeSend = async (data) => {
				// console.log('send', this.webSocketId, tool.data.get('WEBSOCKET_ID'))
				if (this.webSocketId && this.webSocketId !== tool.data.get('WEBSOCKET_ID')) return

				if (
					this.webSocket.readyState !== 1 &&
					(data.indexOf('HeartBeatData') !== -1 || data.indexOf('HangUp_Multi') !== -1)
				) {
					await this.Init()
					this.webSocket.send(data)
				} else if (this.webSocket.readyState === 1) {
					this.webSocket.send(data)
				}
			}

			this.webSocket.onerror = (event) => {
				// 未插话机、未开电话助手
				console.log('error', event)
			}
			this.webSocket.onclose = (event) => {
				console.log('close', event, this.reconnectNum)

				// 关闭接口发送指令
				this.reportCloseWs()

				this.webSocketState = false
				if (this.webSocket.readyState !== 1) {
					this.callback && this.callback('connectedstate', '0')
					this.callback && this.callback('currSIMIndex', null)
					this.callback && this.callback('usedSimList', [])
				}

				// 断线重连
				if (ewaytel.isConnecting) {
					this.callback && this.callback('connectedstate', '2')
					return reject('init close')
				}

				this.clearReconnectTimer(false)
				if (this.reconnectNum < this.maxReconnectNum) {
					this.reconnectTimer = setTimeout(async () => {
						this.reconnectNum++
						await this.Init()
					}, 1000)
				} else {
					this.reconnectNum = 0
					this.callback && this.callback('connectedstate', '2')
				}
				reject('close')
			}
			this.webSocket.onopen = (event) => {
				console.log('open', event)
				this.webSocketState = true
				this.clearHeartBeatTimer()
				this.heartBeatTimer = setInterval(this.HeartBeatCheck.bind(this), 60000) //设置心跳 1分钟间隔
				this.OnOpenDevice()
				resolve()
			}
			// ws消息回调
			this.webSocket.onmessage = async (event) => {
				const setConnectAbort = () => {
					this.clearHeartBeatTimer()
					this.callback && this.callback('connectedstate', '2')
					this.callback && this.callback('currSIMIndex', null)
					this.callback && this.callback('usedSimList', [])
				}

				// 调用接口保存消息
				// console.log('report', this.webSocketId, tool.data.get('WEBSOCKET_ID'))
				if (!this.webSocketId || this.webSocketId === tool.data.get('WEBSOCKET_ID')) {
					await this.saveDataCallback(event.data, this.actionType)
				}

				this.webSocketState = true
				const msgJsonData = JSON.parse(event.data)
				const type = msgJsonData.type
				// console.log('message', type, event)
				if (type === 'CommandResponse') {
					//请求返回
					const state = msgJsonData.data.state
					const command = msgJsonData.data.invoke_command

					if (state) {
						const dynamicdata = msgJsonData.dynamicdata
						if (command === 'GetConnectedState_Multi') {
							this.clearReconnectTimer()

							//设备列表
							const deviceList = dynamicdata.devicelist
							if (!deviceList) {
								// 开电话助手、未插话机
								this.reportCloseWs()
								setConnectAbort()
							} else {
								const currDeviceName = deviceList.split(',')[0]
								this.callback && this.callback('connectedstate', '1')
								this.deviceName = currDeviceName
								this.OnGetTalkState()
								this.OnGetCBCurrState()
								this.OnSetConfig()
							}
						} else if (command === 'CBSwitchNext_Multi') {
							// 顺序换卡
							// console.log('顺序换卡成功')
							this.OnGetCBCurrSIM()
						} else if (command === 'CBSwitch_Multi') {
							// 手动换卡
							// console.log('手动换卡成功')
							this.OnGetCBCurrSIM()
						} else if (command === 'GetDeviceAudio_Multi') {
							//获取音量
						} else if (command === 'GetTalkState_Multi') {
							//获取通话状态
							this.handleTalkState.apply(this, [dynamicdata])
						} else if (command === 'GetCCID_Multi') {
							//获取CCID
						} else if (command === 'GetCBCurrState_Multi') {
							//插卡状态
							const stateList = dynamicdata.split(',')
							const usedList = []
							for (let i = 0; i < 5; i++) {
								stateList[i] !== '0' && usedList.push({ label: 'SIM卡' + (i + 1), value: i })
							}
							this.callback && this.callback('usedSimList', usedList)

							const currSIMStatus =
								!ewaytel.currSIMIndex || usedList.some((item) => item.value === ewaytel.currSIMIndex)
							if (currSIMStatus) {
								this.OnGetCBCurrSIM()
							} else {
								ewaytel.cbSwitchNext('1')
							}
						} else if (command === 'GetCBCurrSim_Multi') {
							//获取当前SIM卡索引
							this.callback && this.callback('currSIMIndex', dynamicdata.simid)
							this.switchCardStatus = false
						} else if (command === 'StopRecord_Multi') {
							//停止录音
						} else if (command === 'GetDeviceInfo_Multi') {
							//获取设备版本信息
						} else if (command === 'GetConfig') {
							//获取配置
						} else if (command === 'SetConfig') {
							//保存配置
						} else if (command === 'SetDeviceAudio_Multi') {
							//保存音量设置
						} else if (command === 'GetUpdloadErrorLog') {
							//获取推送失败通话记录数量
						} else if (command === 'GetUploadErrorRecord') {
							//获取推送失败通话记录数量
						} else if (command === 'RePushAutoUpload') {
							//重新推送完成
						}
					} else {
						if (command === 'Dial_Multi') {
							if (msgJsonData.message) return
							this.fail && this.fail()
						} else if (['CBSwitchNext_Multi', 'CBSwitch_Multi'].includes(command)) {
							this.switchCardStatus = false
							message.warning('换卡失败，请重试!')
						}
					}
				} else if (type === 'DeviceConnectedState') {
					if (msgJsonData.dynamicdata.state) {
						//设备连接状态上报
						// console.log('设备连接状态上报 DeviceConnectedState', msgJsonData.dynamicdata)
						this.OnGetConnectedState()
					} else {
						await this.saveDataCallback(event.data, 0)
						setConnectAbort()
					}
				} else if (type === 'RealTimeState') {
					//设备状态上报
					// console.log('设备状态上报 RealTimeState', msgJsonData.dynamicdata)
					this.handleTalkState.apply(this, [msgJsonData.dynamicdata])
				} else if (type === 'CallRecord') {
					// 正在挂断
					// if (!this.actionType) {
					// 	this.callback && this.callback('talkState', 'hanguping')
					// }
				} else if (type === 'CBCallback') {
					// 拔卡
					this.OnGetCBCurrState()
				}
				resolve()
			}
		}, 200)
	})
}
// 通话处理
Tel4GTxn.prototype.handleTalkState = function (dynamicdata) {
	const { realtimestate, number } = dynamicdata

	// 过滤话机偶尔抽风返回的错误状态
	const ewaytel = ewaytelStore()
	if (ewaytel.isTalkIdle && realtimestate === 'ringback' && !number) return
	if (!this.actionType && ewaytel.talkState !== 'hangup' && realtimestate === 'idle' && !number) return

	// 过滤其他浏览器账号拨打电话响应
	if (this.actionType && ['outgoing', 'incoming'].includes(realtimestate)) {
		this.otherCallStatus = true
	}

	this.callback && this.callback('talkState', realtimestate)
	switch (realtimestate) {
		case 'outgoing':
			break
		case 'ringback':
			break
		case 'incoming':
			break
		case 'outconnected':
			if (!tool.data.get('DIAL_START_TIME')) {
				tool.data.set('DIAL_START_TIME', new Date().getTime())
			}

			if (!this.timingTimer) this.startTiming.apply(this)
			break
		case 'inconnected':
			break
		case 'hangup':
			tool.data.remove('DIAL_START_TIME')

			this.endTiming.apply(this)
			this.callback && this.callback('dialEndTime', new Date())
			break
		case 'idle':
			this.actionType = 1
			this.otherCallStatus = false
			this.callback && this.callback('talkTime', '呼出接通')
			break
		default:
			break
	}
}

Tel4GTxn.prototype.OnOpenDevice = function () {
	this.webSocket.nativeSend('{"command":"OpenDevice_Multi"}')
	this.OnGetConnectedState()
}
// 关闭连接
Tel4GTxn.prototype.OnClose = function () {
	this.clearHeartBeatTimer()
	this.webSocket.close()
	this.webSocketState = false
}

Tel4GTxn.prototype.reportCloseWs = function () {
	// 关闭接口发送指令
	this.deviceName &&
		this.saveDataCallback(
			JSON.stringify({
				data: {
					cid: null,
					invoke_command: 'closeoldws',
					state: true
				},
				dynamicdata: {
					devicename: this.deviceName
				},
				message: '',
				type: 'close'
			}),
			0
		)
}

// 心跳检测
Tel4GTxn.prototype.HeartBeatCheck = function () {
	// console.log('心跳', this.webSocket, this.webSocketState)
	if (this.webSocket && this.webSocketState) {
		this.webSocket.nativeSend('HeartBeatData')
	} else {
		this.Init()
	}
}
// 重连设备
Tel4GTxn.prototype.DeviceReConnect = function () {
	this.webSocket.nativeSend('{"command":"CloseDevice_Multi","arguments":{"devicename":"' + this.deviceName + '"}}')
	this.webSocket.nativeSend('{"command":"OpenDevice_Multi"}')
}

// 设置基础配置信息
Tel4GTxn.prototype.OnSetConfig = function () {
	// 录音相关
	this.webSocket.nativeSend(
		'{"command":"SetConfig", "arguments":{"autorecordenable":"' +
			this.baseConfig.autorecordenable +
			'", "autorecordfilenametype":"' +
			this.baseConfig.autorecordfilenametype +
			'","autouploadlogenable":"' +
			this.baseConfig.autouploadlogenable +
			'","autouploadlogurl":"' +
			this.baseConfig.autouploadlogurl +
			'","autouploadenable":"' +
			this.baseConfig.autouploadenable +
			'","autouploadtype":"' +
			this.baseConfig.autouploadtype +
			'","autouploadurl":"' +
			this.baseConfig.autouploadurl +
			'","accesskeyid":"' +
			this.baseConfig.accesskeyid +
			'","accesskeysecret":"' +
			this.baseConfig.accesskeysecret +
			'","bucketname":"' +
			this.baseConfig.bucketname +
			'","endpoint":"' +
			this.baseConfig.endpoint +
			'","txcospath":"' +
			this.baseConfig.txcospath +
			'","autouploadlogtype":"' +
			this.baseConfig.autouploadlogtype +
			'"}}'
	)
}
// 获取设备连接列表
Tel4GTxn.prototype.OnGetConnectedState = function () {
	this.webSocket.nativeSend('{"command":"GetConnectedState_Multi"}')
}

// 获取当前通话状态
Tel4GTxn.prototype.OnGetTalkState = function () {
	this.webSocket.nativeSend('{"command":"GetTalkState_Multi","arguments":{"devicename":"' + this.deviceName + '"}}')
}
// 读取音量
Tel4GTxn.prototype.OnGetVolume = function () {
	this.webSocket.nativeSend('{"command":"GetDeviceAudio_Multi","arguments":{"devicename":"' + this.deviceName + '"}}')
}

// 获取卡槽状态
Tel4GTxn.prototype.OnGetCBCurrState = function () {
	this.webSocket.nativeSend('{"command":"GetCBCurrState_Multi","arguments":{"devicename":"' + this.deviceName + '"}}')
}
// 获取当前使用SIM卡索引 0-4
Tel4GTxn.prototype.OnGetCBCurrSIM = function () {
	this.webSocket.nativeSend('{"command":"GetCBCurrSim_Multi","arguments":{"devicename":"' + this.deviceName + '"}}')
}
// 顺序换卡
Tel4GTxn.prototype.OnCBSwitchNext = function () {
	this.webSocket.nativeSend('{"command":"CBSwitchNext_Multi","arguments":{"devicename":"' + this.deviceName + '"}}')
}
// 指定索引换卡
Tel4GTxn.prototype.OnCBSwitch = function (simIndex) {
	this.webSocket.nativeSend(
		'{"command":"CBSwitch_Multi","arguments":{"devicename":"' + this.deviceName + '","content":"' + simIndex + '"}}'
	)
}

// 打电话
Tel4GTxn.prototype.OnDial = function (phone) {
	this.actionType = 0
	this.webSocket.nativeSend(
		'{"command":"Dial_Multi","arguments":{"phone":"' + phone + '","devicename":"' + this.deviceName + '"}}'
	)
}
// 挂断
Tel4GTxn.prototype.OnHangup = function () {
	this.actionType = 1
	this.webSocket.nativeSend('{"command":"HangUp_Multi","arguments":{"devicename":"' + this.deviceName + '"}}')
	this.callback && this.callback('talkState', 'hanguping')
}

// 计时
Tel4GTxn.prototype.startTiming = function () {
	this.startTime = tool.data.get('DIAL_START_TIME') // 开始时间
	this.timingTimer = setInterval(this.updateTimer, 1000)
	this.updateTimer() // 初始显示时间
}

// 结束计时
Tel4GTxn.prototype.endTiming = function () {
	if (this.timingTimer) {
		clearInterval(this.timingTimer)
		this.timingTimer = null
	}
}

// 清除心跳
Tel4GTxn.prototype.clearHeartBeatTimer = function () {
	if (this.heartBeatTimer) {
		clearInterval(this.heartBeatTimer)
		this.heartBeatTimer = null
	}
}

// 清除断线重连
Tel4GTxn.prototype.clearReconnectTimer = function (resetNumStatus = true) {
	if (this.reconnectTimer) {
		clearInterval(this.reconnectTimer)
		this.reconnectTimer = null
		if (resetNumStatus) {
			this.reconnectNum = 0
		}
	}
}
